package com.vader.juc.cas;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;

/**
 * @author kaivader
 */
public class LongAddClick {
    public static final int THREAD_SIZE = 50;
    public static final int W = 10000;

    public static void main(String[] args) {
        ClickNumber clickNumber = new ClickNumber();
        CountDownLatch countDownLatch = new CountDownLatch(THREAD_SIZE);
        long old = System.currentTimeMillis();
        for (int i = 0; i < THREAD_SIZE; i++) {

            new Thread(() -> {
                try {
                    for (int j = 0; j < W; j++) {
                        clickNumber.addAtomicLong();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    countDownLatch.countDown();
                }
            }, String.valueOf(i)).start();

        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long newTime = System.currentTimeMillis();
        System.out.println(clickNumber.atomicLong + "\t" + (newTime - old));
    }

}

class ClickNumber {
    int number = 0;

    //151ms
    public synchronized void addSync() {
        number++;
    }

    AtomicInteger atomicInteger = new AtomicInteger();

    //25ms
    public void addAtomicInt() {
        atomicInteger.incrementAndGet();
    }

    AtomicLong atomicLong = new AtomicLong();

    //30ms
    public void addAtomicLong() {
        atomicLong.incrementAndGet();
    }

    LongAdder longAdder = new LongAdder();
    Thread thread = new Thread();

    //20ms
    public void addLongAdd() {
        longAdder.increment();

    }

    LongAccumulator longAccumulator = new LongAccumulator((x, y) -> x + y, 0);

    //28ms
    public void addAccumulator() {
        longAccumulator.accumulate(1L);
    }


}
